#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include<QString>
#include<QDebug>
#include"Process.h"
#include "showwidget.h"
#include<QMessageBox>
#include<QPainter>
#include<QInputDialog>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}




//添加行
void MainWindow::on_addBtn_clicked()
{
    ui->tableWidget->insertRow(ui->tableWidget->rowCount());
    ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,3,new QTableWidgetItem("0"));
}


//确定  用于读取表格数据到任务管理器中
void MainWindow::on_okBtn_clicked()
{
    //读取表格中的内容到任务调度管理器ProcessManager中
    pm=ProcessManager();
    for (int i=0;i<ui->tableWidget->rowCount();i++)
    {
        Process p;
        string name=ui->tableWidget->item(i,0)->text().toStdString();
        double createTime=ui->tableWidget->item(i,1)->text().toDouble();
        double needTime=ui->tableWidget->item(i,2)->text().toDouble();
        double priority=ui->tableWidget->item(i,3)->text().toDouble();
        p.name=name;
        p.createTime=createTime;
        p.needTime=needTime;
        p.priority=priority;
        pm.processBook.push_back(p);
    }
    pm.InitProcessControl();
    QMessageBox::information(this,"提示","保存成功");

    //测试代码
    for (int i=0;i<pm.processBook.size();i++)
    {
        QString qBuff=QString::fromStdString(pm.processBook[i].name);
        qDebug()<<"进程号"<<qBuff<<" ";
        double doubleBuff=pm.processBook[i].createTime;
        qDebug()<<"创建时间"<<doubleBuff<<" ";
        doubleBuff=pm.processBook[i].needTime;
        qDebug()<<"运行时间"<<doubleBuff<<" ";
    }

}


//先来先服务
void MainWindow::on_paintBtn_clicked()
{
    state=1;
    update();
    pm.RunTime(this,3,rateForPaint,systemTime);
}

//x,y,宽,高
//绘图事件
void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.save();
    if (state==1||state==2)
    {
        QPoint p_0(50,250);//process_0进程的左上角
        int height=50;//统一矩形高度
        double width=0;//变量为宽度
        double width_pre=0;//上一个矩形的宽度
        int ratio=10;//宽度放大倍数

        //绘制时间进度
        painter.setBrush(QColorConstants::Green);//设置为填充绿色
        double realTime=pm.realTime;//模拟时间
        QString rt="现在的时间:"+QString::number(realTime);//模拟时间的QString 形式
        painter.drawText(90+realTime*ratio,230,rt);//绘制时间文本
        painter.drawRect(90,230,realTime*ratio,20);//绘制时间矩形
        painter.restore();//取消填充绿色的模式


        //绘制process_0的图形(任务队列，进程未创建)
        for (int i=0;i<pm.processControl[0].size();i++)
        {
            QString qstr=QString::fromStdString(pm.processControl[0][i].name);//输出进程号
            width=pm.processControl[0][i].needTime*ratio;
            painter.drawRect(90+width_pre,250,width,height);
            painter.drawText(90+width_pre+width/3,250+height/2,qstr);//绘制进程号
            width_pre+=width;
        }
        //绘制process_1的图形(等待队列，进程已创建，但未执行)
        width=0;
        width_pre=0;
        for (int i=0;i<pm.processControl[1].size();i++)
        {
            QString qstr=QString::fromStdString(pm.processControl[1][i].name);//输出进程号
            width=pm.processControl[1][i].needTime*ratio;
            painter.drawRect(90+width_pre,310,width,height);
            painter.drawText(90+width_pre+width/3,310+height/2,qstr);
            width_pre+=width;
        }
        //绘制process_2的图形(运行队列,进程正在执行)
        width=0;
        width_pre=0;
        for (int i=0;i<pm.processControl[2].size();i++)
        {
            QString qstr=QString::fromStdString(pm.processControl[2][i].name);//输出进程号
            width=pm.processControl[2][i].needTime*ratio;
            painter.drawRect(90+width_pre,370,width,height);

            painter.setBrush(QColorConstants::Green);
            if (state==1)painter.drawRect(90+width_pre,370,(realTime-pm.processControl[2][i].startTime)*ratio,height);//绘制加载动画
            if (state==2)painter.drawRect(90+width_pre,370,pm.processControl[2][i].priority*ratio,height);//时间片轮转特有动画
            painter.drawText(90+width_pre+width/3,370+height/2,qstr);
            painter.restore();
            width_pre+=width;
        }

        //绘制process_3的图形(结束队列,进程执行完毕)
        width=0;
        width_pre=0;
        for (int i=0;i<pm.processControl[3].size();i++)
        {
            QString qstr=QString::fromStdString(pm.processControl[3][i].name);//输出进程号
            width=pm.processControl[3][i].needTime*ratio;

            painter.setBrush(QColorConstants::Green);
            painter.drawRect(90+width_pre,430,width,height);
            painter.drawText(90+width_pre+width/3,430+height/2,qstr);
            width_pre+=width;
        }

        //计算平均周转时间与平均带权周转时间
        double aveTime=0;
        double aveTimeWithWeight=0;
        for (vector<Process>::iterator it = pm.processControl[3].begin(); it != pm.processControl[3].end();it++)
        {
            aveTime += it->turnaroundTime;
            aveTimeWithWeight += it->timeWithWeight;
        }
        aveTime /= pm.processControl[3].size();
        aveTimeWithWeight /= pm.processControl[3].size();
        for (int i=0;i<pm.processControl[3].size();i++)
        {
            //绘制统计结果
            QString result="  进程号: "+QString::fromStdString(pm.processControl[3][i].name)+
                             "  创建时间: "+QString::number(pm.processControl[3][i].createTime)+
                "  运行时间:  "+QString::number(pm.processControl[3][i].needTime)+
                "  开始时间:  "+QString::number(pm.processControl[3][i].startTime)+
                "  结束时间:  "+QString::number(pm.processControl[3][i].endTime)+
                "  周转时间:   "+QString::number(pm.processControl[3][i].turnaroundTime)+
                "  带权周转时间: "+QString::number(pm.processControl[3][i].timeWithWeight);
            painter.drawText(90,500+i*20,result);
            if (i==pm.processControl[3].size()-1) painter.drawText(90,500+(i+1)*20,"  平均周转时间:  "+QString::number(aveTime)+"  平均带权周转时间:  "+QString::number(aveTimeWithWeight));
        }
        //state=0;//控制绘图事件

    }
}


void MainWindow::on_paintBtn_2_clicked()
{
    state=1;
    update();
    pm.RunTime(this,4,rateForPaint,systemTime);
}

//响应比优先
void MainWindow::on_paintBtn_3_clicked()
{
    state=1;
    update();
    pm.RunTime(this,6,rateForPaint,systemTime);
}

//优先级优先(非抢占式)
void MainWindow::on_paintBtn_4_clicked()
{
    state=1;
    update();
    pm.RunTime(this,5,rateForPaint,systemTime);
}

//时间片流转
void MainWindow::on_paintBtn_5_clicked()
{
    state=2;
    update();
    pm.ServeForRotation(this,rateForPaint,systemTime);
}

//设置绘图频率
void MainWindow::on_setRateForPaintBtn_clicked()
{
    this->rateForPaint=QInputDialog::getInt(this,"设置绘图频率","请输入绘图频率\n单位为毫秒\n建议设置为50-500之间\n默认为50");
}

//设置线程生命周期
void MainWindow::on_setSystemTimeBtn_clicked()
{
    this->systemTime=QInputDialog::getInt(this,"设置线程生命周期","请输入线程的生命周期\n单位为秒\n输入值意味着这个线程执行多长时间后停下来\n默认为15秒");
}

//使用说明
void MainWindow::on_helpBtn_clicked()
{
    QString helpStr="点击添加进程，输入相关值后，点击确定，即可点击任意算法按钮开始执行\n\n注意:\n1.点击设置绘图率与设置线程周期可以设置相关值,但是不设置也可以运行\n2.如果您觉得程序速度太快了，可以在'设置绘图频率'按钮中调整\n3.执行'优先级优先'算法需要在表格的'优先级'中填入相关值，值越大越优先\n4.不要在未输入任何值的时候点击确定，否则程序会崩溃";
    QMessageBox::information(this,"使用说明",helpStr);
}

